package org.yoshiori.commons.security;

import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.yoshiori.commons.security.MessageDigest.DigestAlgorithm;
import org.yoshiori.hatena.HatenaException;

public class WSSE {

    private static final Log log = LogFactory.getLog(WSSE.class);

    private static SecureRandom random;

    private static final SimpleDateFormat format = new SimpleDateFormat(
            "yyyy-MM-dd'T'HH:mm:ss'Z'");

    private static final MessageDigest digest = new MessageDigest(
            DigestAlgorithm.SHA_1);

    static {
        try {
            random = SecureRandom.getInstance("SHA1PRNG");
        } catch (NoSuchAlgorithmException e) {
            log.error(e, e);
        }
        format.setTimeZone(TimeZone.getTimeZone("GMT"));
    }

    public static String getWsseHeaderValue(String username, String password) {
        byte[] nonce = new byte[10];
        random.nextBytes(nonce);
        String created = format.format(new Date());
        String passwordDigest = null;
        try {
            passwordDigest = new String(
                    Base64.encodeBase64(
                            digest.getByts(
                                    ArrayUtils.addAll(ArrayUtils.addAll(nonce,created.getBytes("UTF-8")),
                                            password.getBytes("UTF-8")))));
        } catch (UnsupportedEncodingException e) {
            throw new HatenaException(e);
        }
        StringBuilder value = new StringBuilder("UsernameToken Username=\"")
                                    .append(username)
                                    .append("\", PasswordDigest=\"")
                                    .append(passwordDigest)
                                    .append("\", Nonce=\"")
                                    .append(new String(Base64.encodeBase64(nonce)))
                                    .append("\", Created=\"")
                                    .append(created).append('"');
        if(log.isDebugEnabled()){
            log.debug("WSSE value is -" + value.toString() + "-");
        }
        return value.toString();
    }
}
